本系列文章已出版實體書籍:
「你的地圖會說話?WebGIS 與 JavaScript 的情感交織」(博碩文化)
WebGIS啟蒙首選✖五家地圖API✖近百個程式範例✖實用簡易口訣✖學習難度分級✖補充ES6小知識
原本這篇預定要介紹ArcGIS API for JavaScript,
但是想想如果繼續介紹點、線、面、圖層套疊等等,
只是換個圖台API,換個寫法,未免無趣。
因此我總是想找一些屬於該API特有的,介紹給大家認識,
找來找去決定來玩玩看3D地圖?!
ArcGIS API為了簡化開發過程,使用了Dojo框架做為整體架構,起初在3.33版本時dojo最重要的功用為dojo.require,為達到非同步模組化管理
,也就是所謂的AMD規範。早期JavaScript尚未有良好的模組化管理系統,隨著程式越寫越龐大,JS分支越來越多,再加上JS非同步的概念,想要讓程式獨立而不依賴瀏覽器DOM的Include,必須靠別的手段去實現,而dojo.require就是一個很好的管理工具。
↓ 以HTML include方式載入每個模組,ArcGIS API不使用此方法。
<script src="https://js.arcgis.com/4.16/esri/map"></script>
↓ 以dojo方式載入模組(舊式寫法)
dojo.require("esri.map");
↓ ArcGIS API已全面支援AMD,所有模組皆以define()的方式輸出,並以require方式載入。
require(["esri/map", ... ], function(Map, ... ){
// 在這邊使用輸出的Map或其他模組
});
↓ 以dojo/ready模組可以讓程式在DOM載入完畢時才觸發,效果同JQ的$(document).ready()
require(["dojo/ready"], function (ready) {
ready(function () {
// DOM載入完畢時觸發
});
});
↓ 以dojo/on模組可以為dom元素增加監聽事件。(舊版寫法為dojo.connect)
require(["esri/map", "dojo/on"], function (Map, on) {
on(myMap, "load", callback); // 事件觸發callback函式
});
↓ 載入css與js
<link rel="stylesheet" href="https://js.arcgis.com/3.33/esri/css/esri.css">
<script src="https://js.arcgis.com/3.33/"></script>
↓ 利用require方式載入底圖模組("esri/basemaps")、地圖模組("esri/map")、dojo.ready模組("dojo/domReady!")。
require([
"esri/basemaps",
"esri/map",
"dojo/domReady!"
], function (esriBasemaps, Map) {
esriBasemaps.delorme = { // 設定底圖
baseMapLayers: [{ url: "https://services.arcgisonline.com/ArcGIS/rest/services/Specialty/DeLorme_World_Base_Map/MapServer" }
],
thumbnailUrl: "https://www.example.com/images/thumbnail_2014-11-25_61051.png",
title: "Delorme"
};
var map = new Map("amap", { // 初始化地圖
basemap: "delorme",
center: [121, 23.5],
zoom: 8,
sliderStyle: "small"
});
});
↓ 結果
然而,ArcGIS API已宣布2022年將會停用3.33版本,全面改用最新的4.16版本。
在新的版本中,新增了View的概念,在使用Map模組初始化地圖後,
還需要把它新建在view中與DOM元素做綁定,
這也代表了一個地圖可以重複使用,並且可以不只綁定在一個dom元素上。
MapView是用來做為2D地圖使用,SceneView則是用來做為3D地圖使用。
↓ 載入ArcGIS API 4.16版本
<link rel="stylesheet" href="https://js.arcgis.com/4.16/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.16/"></script>
↓ 存放地圖的div
<div id="amap"></div>
↓ 載入地圖模組("esri/Map")、2D視覺模組("esri/views/MapView")
require([
"esri/Map",
"esri/views/MapView"
], function (Map, MapView) {
var map = new Map({
basemap: "topo-vector" // 底圖
});
var view = new MapView({
container: "amap",
map: map,
center: [121, 23.5],
zoom: 8,
});
});
↓ 結果
↓ 載入地圖模組("esri/Map")、3D視覺模組("esri/views/SceneView")
require([
"esri/Map",
"esri/views/SceneView",
], function (Map, SceneView) {
var map = new Map({
basemap: "topo-vector",
ground: "world-elevation"
});
var view = new SceneView({
container: "amap",
map: map,
camera: {
position: {
x: 121,
y: 23.5,
z: 18000 // 設定觀看高度(公尺)
},
tilt: 75
}
});
});
↓ 結果讓我們一同眺望中央山脈的雄偉!
ArcGIS為GIS界大佬ESRI公司所開發,有諸多產品如ArcGIS for Desktop、ArcGIS Online等。如果今天在ArcGIS Online建立地圖,並且加入圖層並做一些修改過後,想要直接在WebGIS上載入,只要透過ArcGIS認證的一組id就可以輕鬆載入啦!
↓ 載入WebScene模組("esri/WebScene"),用以載入ArcGIS Online上面的專案。
這邊用ArcGIS API範例的專案。
require([
"esri/Map",
"esri/WebScene",
"esri/views/SceneView",
], function (Map, WebScene, SceneView) {
const webscene = new WebScene({
portalItem: {
id: "579f97b2f3b94d4a8e48a5f140a6639b" // 專案id
}
});
console.log(webscene);
const view = new SceneView({
container: "amap",
map: webscene,
camera: {
position: {
x: -118.808,
y: 33.961,
z: 2000
},
tilt: 75
}
});
↓ 結果
用ArcGIS Server發佈的圖層可以藉由FeatureLayer加入3D地圖中。
↓ ArcGIS Server發佈的圖層介面,這邊使用的也是ArcGIS的範例圖層之一。
↓ 載入FeatureLayer模組("esri/FeatureLayer")
require([
"esri/Map",
"esri/views/SceneView",
"esri/layers/FeatureLayer"
], function (Map, SceneView, FeatureLayer) {
const map = new Map({
basemap: "topo-vector",
ground: "world-elevation"
});
const view = new SceneView({
container: "amap",
map: map,
camera: {
position: {
x: -118.808,
y: 33.961,
z: 2000
},
tilt: 75
}
});
// 點圖層
const featureLayer = new FeatureLayer({
url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads/FeatureServer/0"
});
map.add(featureLayer);
// 線圖層
const trailsLayer = new FeatureLayer({
url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails/FeatureServer/0"
});
map.add(trailsLayer, 0);
// 面圖層
const parksLayer = new FeatureLayer({
url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Parks_and_Open_Space/FeatureServer/0"
});
map.add(parksLayer, 0);
});
↓ 結果
今天簡單介紹了ArcGIS API從3.33到4.16的演變,
用dojo框架定義模組,並且建立2D、3D地圖,
大家有空可以玩玩看!(不用api key很方便)
然而,dojo.require引入模組的方式要怎麼設定,
要怎麼去定義模組、輸出模組?ES6以後又有什麼語法可以取代require?
明天要講解require.js的使用方式以及ES6 Import!
不要錯過囉!